/*
 * Copyright 2009 Eric S Landry 
 * 
 * Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package ca.ericslandry;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * Class to help me put files in my custom directory structure.
 * </p>
 * <p>
 * Moves picture files in custom directory structure based on file timestamp.
 * Expected directory structure: [rootdir]/yyyy/mm/yyyy_mm_dd/[photoFiles]
 * </p>
 * <p>
 * Please note that there are a bunch of efficiencies and prettifications that
 * I've ommited because it did what I wanted to do.
 * </p>
 * @author <a href="mailto:eric.s.landry@gmail.com">Eric S. Landry</a>
 */
public class PhotoOrganizer {
	// TODO: Change to suit your needs
	private static final String START_DIR = "c:\\media";

	// File extensions to include
	private static final Pattern REGEX_PATTERN = Pattern
			.compile(".*\\.(png|PNG|jpg|JPG|avi|AVI|gif|GIF|mov|MOV|wmv|WMV|mpg|MPG|mpeg|MPEG|crw|CRW|bmp|BMP|thm|THM|tif|TIF)");

	private List<String> ignoredList = new ArrayList<String>();

	public PhotoOrganizer() {
		File startdir = new File(START_DIR);
		traverseTree(startdir);
		System.out.println(ignoredList);
	}

	private void traverseTree(File startNode) {
		String[] children = startNode.list();
		if (children == null) {
			if (isProcessable(startNode)) {
				checkTime(startNode);
			}
		}
		else {
			System.out.println(" Processing files in: " + startNode);
			for (int i = 0; i < children.length; i++) {
				traverseTree(new File(startNode, children[i]));
			}
		}
	}

	private boolean isProcessable(File file) {
		Matcher matcher = REGEX_PATTERN.matcher(file.getName());
		if (file.exists() && file.isFile()) {
			if (matcher.matches()) {
				return true;
			}
			String name = file.getName();
			// Ignore Picasa config files
			if (!name.endsWith(".info") && !name.endsWith(".db")
					&& !name.endsWith(".ini")) {
				ignoredList.add(file.getName());
			}
		}
		return false;
	}

	private void checkTime(File file) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTimeInMillis(file.lastModified());

		int day = calendar.get(Calendar.DAY_OF_MONTH);
		int month = calendar.get(Calendar.MONTH) + 1;
		int year = calendar.get(Calendar.YEAR);

		String sYear = String.valueOf(year);
		String sMonth = (month < 10) ? "0" + month : String.valueOf(month);
		String sDay = (day < 10) ? "0" + day : String.valueOf(day);

		StringBuffer expectedPath = new StringBuffer();
		expectedPath.append(START_DIR).append(File.separatorChar).append(sYear)
				.append(File.separatorChar).append(sMonth).append(
						File.separatorChar).append(sYear).append("_").append(
						sMonth).append("_").append(sDay);

		String actualPath = file.getPath().substring(0,
				file.getPath().lastIndexOf(File.separatorChar));

		if (!actualPath.equals(expectedPath.toString())) {
			System.out.println("\nChecking file:  " + file.getName());
			System.out.println("Should be in:     " + expectedPath);
			System.out.println("But actually in:  " + actualPath);

			File expectedDir = new File(expectedPath.toString());
			if (!expectedDir.exists()) {
				expectedDir.mkdir();
			}
			File target = new File(expectedDir, file.getName());
			boolean movedSuccessfully = file.renameTo(target);

			if (!movedSuccessfully) {
				if (target.exists() && target.length() == file.length()) {
					System.out.println("The file already exists - deleting "
							+ file);
					file.delete();
				}
				else {
					System.out
							.println("The move failed for someunknown reason.");
				}
			}
		}
	}

	public static void main(String[] args) {
		new PhotoOrganizer();
	}
}
